package com.yishe.utils;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYYMM = "yyyyMM";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String HHMMSSS = "HHmmsss";
    public static final String YYYY = "yyyy";
    /**
     * @param startDate
     * @param endDate
     * @return null
     * @Description: [获取工作日天数]
     * @author lh
     * @CreateDate: 2020/1/8 18:10
     * @update: [序号][日期YYYY-MM-DD] [更改人姓名][变更描述]
     */
    public static int getWorkingDay(String startDate, String endDate) throws Exception {
        int days = 0;
        int workdays = 0;
        int weeks = 0;
        try {
            SimpleDateFormat format = new SimpleDateFormat(
                    "yyyy-MM-dd");
            Date date_start = format.parse(endDate);
            Date date_end = format.parse(startDate);
            Calendar cal_start = Calendar.getInstance();
            Calendar cal_end = Calendar.getInstance();
            cal_start.setTime(date_start);
            cal_end.setTime(date_end);
            workdays = getWorkingDay(cal_start, cal_end);
        } catch (Exception ex) {

        }
        return workdays;
    }

    /**
     * 计算2个日期之间的相隔工作天数
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int getWorkingDay(Calendar d1, Calendar d2) {
        int result = -1;
        if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }

        //long betweendays = getDaysBetween(d1, d2);


        //int charge_date = 0;
        int charge_start_date = 0;//开始日期的日期偏移量
        int charge_end_date = 0;//结束日期的日期偏移量
        // 日期不在同一个日期内
        int stmp;
        int etmp;
        stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
        etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);
        if (stmp != 0 && stmp != 6) {// 开始日期为星期六和星期日时偏移量为0
            charge_start_date = stmp - 1;
        }
        if (etmp != 0 && etmp != 6) {// 结束日期为星期六和星期日时偏移量为0
            charge_end_date = etmp - 1;
        }
        result = (getDaysBetween(getNextMonday(d1), getNextMonday(d2)) / 7)
                * 5 + charge_start_date - charge_end_date;
        return result;
    }

    //两个日期间的自然日
    public static int getDaysBetween(Calendar d1, Calendar d2) {
        if (d1.after(d2)) { // swap dates so that d1 is start and d2 is end
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(Calendar.DAY_OF_YEAR)
                - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);
        if (d1.get(Calendar.YEAR) != y2) {
            d1 = (Calendar) d1.clone();
            do {
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
                d1.add(Calendar.YEAR, 1);
            } while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }

    /**
     * 获得日期的下一个星期一的日期
     *
     * @param date
     * @return
     */
    public static Calendar getNextMonday(Calendar date) {
        Calendar result = null;
        result = date;
        do {
            result = (Calendar) result.clone();
            result.add(Calendar.DATE, 1);
        } while (result.get(Calendar.DAY_OF_WEEK) != 2);
        return result;
    }
    /**
     * 根据输入的时间格式获取当前系统时间
     * @return String
     */
    public static String getNow(String pattern) {
        if (null == pattern ||"".equals(pattern)){
            pattern=YYYY_MM_DD_HH_MM_SS;
        }
        return getDateTime(System.currentTimeMillis(),pattern);
    }

    /**
     * 根据传入的long类型时间和时间格式，输出对应格式的字符串
     * @param time
     * @param pattern
     * @return
     */
    public static String getDateTime(long time,String pattern){
        DateTime dateTime = new DateTime(time);
        return dateTime.toString(pattern);
    }

    /**
     * 获取制定格式化当前时间
     * @param pattern
     * @return
     */
    public static Date getNowDate(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD);
        DateTimeFormatter formatter = DateTimeFormat.forPattern(YYYY_MM_DD);
       return DateTime.parse(sdf.format(new Date()),formatter).toDate();
    }

    public static void main(String[] args) {
        System.out.println(getNowDate("yyyy-MM-dd"));
    }
    /**
     * 根据传入的字符串时间和对应时间格式，输出Date
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date getDate(String time,String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (null ==time) {
            return null;
        }
        return sdf.parse(time);
    }
    public static Date getDateByDate(Date input,String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (null ==input) {
            return null;
        }
        String formaterStr = sdf.format(input);
        return getDate(formaterStr,pattern);
    }

    /**
     * 获取传入数据的上一年度
     */
    public static String getPreYearDate(String currentTime){
        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
        Date time = null;
        try {
            time = sdf.parse(currentTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(Calendar.YEAR,-1);
        return sdf.format(c.getTime());
    }
    /**
     * 判断是否是闰年
     *
     * @param year
     * @return
     */
    private static boolean isLeapYear(String year) {
        if (null == year || "0".equals(year)) {
            throw new RuntimeException("输入年份格式有误，重新输入");
        }
        Integer y = Integer.valueOf(year);
        return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
    }
    /**
     * 返回月份结尾时间
     */
    public static String executeEndDay(String time) {
        String year = time.substring(0, 4);
        String month = time.substring(5, 7);
        if ("02".equals(month)) {
            if (isLeapYear(year)) {
                return "29";
            } else {
                return "28";
            }
        } else if ("04".equals(month) || "06".equals(month) || "09".equals(month) || "11".equals(month)) {
            return "30";
        } else {
            return "31";
        }
    }
    /**
     * 返回输入时间和间隔时间基数的下一时间
     * @param input 输入的时间
     * @param days 间隔天数
     * @param isAdd true 加 false 减
     */
    public static Date getNextDate(Date input,int days,boolean isAdd){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(input);
        if (isAdd) {
            calendar.add(Calendar.DATE, days);
        } else {
            calendar.add(Calendar.DATE,-days);
        }
        return calendar.getTime();
    }
}
